package com.demo.algorithm;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by hunter
 *
 * @Description LRU Least Recently Used，即最近最久未使用的意思, 这里简单实现一个末尾最长时间未用淘汰的缓存。
 *              借用了linkedHashMap的方法实现。而此实现即putVal是调用重写的afterNodeAccess 将更新节点移至最后实现,
 *              我们再重写它的removeEldestEntry 即添加移除条件即可。
 */
public class LRUCache<K, V> {

    private static final float LOAD_FACTORY = 0.75F;
    private Map<K, V> map;
    private int initialCapacity;

    LRUCache(int initialCapacity) {
        this(initialCapacity, LOAD_FACTORY);
    }

    LRUCache(int initialCapacity, float loadFactory) {
        this.initialCapacity = initialCapacity;
        int capacity = (int) Math.ceil(initialCapacity / loadFactory) + 1;
        map = new LinkedHashMap<K, V>(capacity, loadFactory, true) {
            private static final long serialVersionUID = 1L;

            @Override
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > LRUCache.this.initialCapacity;
            }
        };
    }

    public synchronized V get(K key) {
        return map.get(key);
    }

    public synchronized void put(K key, V value) {
        map.put(key, value);
    }

    public synchronized void clear() {
        map.clear();
    }

    public synchronized int usedSize() {
        return map.size();
    }

    public void print() {
        for (Map.Entry<K, V> entry : map.entrySet()) {
            System.out.print(entry.getValue() + "--");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        LRUCache<String, Object> cache = new LRUCache<>(5);

        cache.put("1", 1);
        cache.put("2", 2);
        cache.put("3", 3);
        cache.put("4", 4);
        cache.put("5", 5);
        cache.print();

        cache.put("6", 6);
        cache.print();

        cache.put("3", 3);
        cache.print();

    }
}
